#include "stdafx.h"
#include "Player.h"
#include "ChessPiece.h"
#include "ChessBoard.h"
#include "ChessKing.h"
#include "ChessQueue.h"
#include "ChessBiShop.h"
#include "ChessKnight.h"
#include "ChessRook.h"
#include "ChessPawn.h"

HRESULT Player::Initialize(const std::shared_ptr<ChessBoard>& chess_board)
{
    // Create 8 pawns, two rooks, two knights, two bishops, one queue and one king
    RETURN_AND_RECORD_ERROR_MESSAGE_IF_NULL(m_chess_board = chess_board)
    if (m_type_name == 1)
    {
        ChessPiece* pawn1 = new ChessPawn(1, 0);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetTypeName(1))

        ChessPiece* pawn2 = new ChessPawn(1, 1);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetTypeName(1))

        ChessPiece* pawn3 = new ChessPawn(1, 2);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetTypeName(1))

        ChessPiece* pawn4 = new ChessPawn(1, 3);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetTypeName(1))

        ChessPiece* pawn5 = new ChessPawn(1, 4);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetTypeName(1))

        ChessPiece* pawn6 = new ChessPawn(1, 5);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetTypeName(1))

        ChessPiece* pawn7 = new ChessPawn(1, 6);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetTypeName(1))

        ChessPiece* pawn8 = new ChessPawn(1, 7);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetTypeName(1))

        ChessPiece* rook1 = new ChessRook(0, 0);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetChessType(e_rook))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetTypeName(1))

        ChessPiece* rook2 = new ChessRook(0, 7);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetChessType(e_rook))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetTypeName(1))

        ChessPiece* knight1 = new ChessKnight(0, 1);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetChessType(e_knight))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetTypeName(1))

        ChessPiece* knight2 = new ChessKnight(0, 6);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetChessType(e_knight))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetTypeName(1))

        ChessPiece* bishop1 = new ChessBiShop(0, 2);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetChessType(e_bishop))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetTypeName(1))

        ChessPiece* bishop2 = new ChessBiShop(0, 5);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetChessType(e_bishop))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetTypeName(1))

        ChessPiece* queue = new ChessQueue(0, 3);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetChessType(e_queue))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetTypeName(1))

        ChessPiece* king = new ChessKing(0, 4);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetChessType(e_king))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetTypeName(1))

        m_vec_pieces.push_back(pawn1);
        m_vec_pieces.push_back(pawn2);
        m_vec_pieces.push_back(pawn3);
        m_vec_pieces.push_back(pawn4);
        m_vec_pieces.push_back(pawn5);
        m_vec_pieces.push_back(pawn6);
        m_vec_pieces.push_back(pawn7);
        m_vec_pieces.push_back(pawn8);
        m_vec_pieces.push_back(rook1);
        m_vec_pieces.push_back(rook2);
        m_vec_pieces.push_back(knight1);
        m_vec_pieces.push_back(knight2);
        m_vec_pieces.push_back(bishop1);
        m_vec_pieces.push_back(bishop2);
        m_vec_pieces.push_back(queue);
        m_vec_pieces.push_back(king);
    }
    else if (m_type_name == 2)
    {
        ChessPiece* pawn1 = new ChessPawn(6, 0);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn1->SetTypeName(2))

        ChessPiece* pawn2 = new ChessPawn(6, 1);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn2->SetTypeName(2))

        ChessPiece* pawn3 = new ChessPawn(6, 2);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn3->SetTypeName(2))

        ChessPiece* pawn4 = new ChessPawn(6, 3);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn4->SetTypeName(2))

        ChessPiece* pawn5 = new ChessPawn(6, 4);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn5->SetTypeName(2))

        ChessPiece* pawn6 = new ChessPawn(6, 5);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn6->SetTypeName(2))

        ChessPiece* pawn7 = new ChessPawn(6, 6);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn7->SetTypeName(2))

        ChessPiece* pawn8 = new ChessPawn(6, 7);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetChessType(e_pawn))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(pawn8->SetTypeName(2))

        ChessPiece* rook1 = new ChessRook(7, 0);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetChessType(e_rook))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook1->SetTypeName(2))

        ChessPiece* rook2 = new ChessRook(7, 7);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetChessType(e_rook))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(rook2->SetTypeName(2))

        ChessPiece* knight1 = new ChessKnight(7, 1);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetChessType(e_knight))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight1->SetTypeName(2))

        ChessPiece* knight2 = new ChessKnight(7, 6);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetChessType(e_knight))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(knight2->SetTypeName(2))

        ChessPiece* bishop1 = new ChessBiShop(7, 2);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetChessType(e_bishop))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop1->SetTypeName(2))

        ChessPiece* bishop2 = new ChessBiShop(7, 5);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetChessType(e_bishop))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(bishop2->SetTypeName(2))

        ChessPiece* queue = new ChessQueue(7, 3);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetChessType(e_queue))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(queue->SetTypeName(2))

        ChessPiece* king = new ChessKing(7, 4);
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetChessType(e_king))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetChessBoard(m_chess_board))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetSelect(FALSE))
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(king->SetTypeName(2))

        m_vec_pieces.push_back(pawn1);
        m_vec_pieces.push_back(pawn2);
        m_vec_pieces.push_back(pawn3);
        m_vec_pieces.push_back(pawn4);
        m_vec_pieces.push_back(pawn5);
        m_vec_pieces.push_back(pawn6);
        m_vec_pieces.push_back(pawn7);
        m_vec_pieces.push_back(pawn8);
        m_vec_pieces.push_back(rook1);
        m_vec_pieces.push_back(rook2);
        m_vec_pieces.push_back(knight1);
        m_vec_pieces.push_back(knight2);
        m_vec_pieces.push_back(bishop1);
        m_vec_pieces.push_back(bishop2);
        m_vec_pieces.push_back(queue);
        m_vec_pieces.push_back(king);
    }
    else
    {
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FALSE(FALSE)
    }

    return S_OK;
}

HRESULT Player::SetTurn(BOOL is_turn)
{
    m_is_turn = is_turn;

    return S_OK;
}

HRESULT Player::GetTurn(BOOL& is_turn) const
{
    is_turn = m_is_turn;

    return S_OK;
}

HRESULT Player::SetAllPieces(std::vector<ChessPiece*> vec_pieces)
{
    m_vec_pieces.clear();
    m_vec_pieces = vec_pieces;

    return S_OK;
}

HRESULT Player::GetAllPieces(std::vector<ChessPiece*>& vec_pieces) const
{
    vec_pieces.clear();
    vec_pieces = m_vec_pieces;

    return S_OK;
}

HRESULT Player::IsSelectPieces(BOOL& is_select)
{
    is_select = m_is_select;

    return S_OK;
}

HRESULT Player::SetNoSelectPieces()
{
    size_t size = m_vec_pieces.size();
    for (int index = 0; index < size; ++index)
    {
        RETURN_AND_RECORD_ERROR_MESSAGE_IF_FAILED(m_vec_pieces[index]->SetSelect(FALSE))
    }

    return S_OK;
}